home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 23 code / Internet Config / IC 1.1 / ICProgKit1.1 / Examples / Space Aliens / SpaceAliens.p < prev    next >
Encoding:
Text File  |  1995-02-05  |  8.4 KB  |  300 lines  |  [TEXT/PJMM]

  1. program SpaceAliens;
  2.     (* Space Aliens Ate My Icons *)
  3.     (* A drag and drop utility to fix the type and *)
  4.     (* creator of any dropped on file based on its *)
  5.     (* extension and the database of extension mappings *)
  6.     (* provided by Internet Config. *)
  7.  
  8.     uses
  9.         (* standard system units needed to do AppleEvents *)
  10.         (* remember that Think Pascal automatically uses *)
  11.         (* most of the base operating system *)
  12.         EPPC, AppleEvents, 
  13.  
  14.         (* standard IC units *)
  15.         ICTypes, ICAPI, ICKeys, 
  16.  
  17.         (* bonus IC units, extra libraries shipped *)
  18.         (* as source code *)
  19.         ICMappings, ICSubs;
  20.  
  21. (* ***** Standard Subroutines ***** *)
  22.  
  23.     function GotRequiredParams (theAppleEvent: AppleEvent): OSErr;
  24.         (* standard AppleEvent routine copied out of NIM:IAC *)
  25.         var
  26.             typeCode: DescType;
  27.             actualSize: Size;
  28.             err: OSErr;
  29.     begin
  30.         err := AEGetAttributePtr(theAppleEvent,
  31.                             keyMissedKeywordAttr, typeWildCard,
  32.                             typeCode, nil, 0, actualSize);
  33.         if err = errAEDescNotFound then begin
  34.             GotRequiredParams := noErr;
  35.         end
  36.         else if err = noErr then begin
  37.             GotRequiredParams := errAEEventNotHandled;
  38.         end
  39.         else begin
  40.             GotRequiredParams := err;
  41.         end; (* if *)
  42.     end; (* GotRequiredParams *)
  43.  
  44. (* ***** Global Declarations ***** *)
  45.  
  46.     const
  47.         my_creator = 'SA8I';
  48.                     (* the application signature *)
  49.     var
  50.         quit_now: boolean;
  51.                     (* set to true when you want main loop to quit *)
  52.         instance: ICInstance;
  53.                     (* global connection to IC *)
  54.         mappings: Handle;
  55.                     (* the mapping preference as returned by IC *)
  56.  
  57. (* ***** Do The Hard Stuff ***** *)
  58.  
  59.     function ProcessDocument (fss: FSSpec): OSErr;
  60.         (* this is the core of the program *)
  61.         (* the fss parameter is a file whose extension *)
  62.         (* we'll look up in the IC database *)
  63.         (* mappings global variable is already set up *)
  64.         (* to contain that database *)
  65.         var
  66.             err: OSErr;
  67.             count: longint;
  68.                         (* total number of entries in database *)
  69.             i: longint;
  70.                         (* indexes over the database entries *)
  71.             this: ICMapEntry;
  72.                         (* an unpacked element of the *)
  73.                         (* mappings database, used while stepping *)
  74.                         (* through database *)
  75.             entry: ICMapEntry;
  76.                         (* an mappings database element *)
  77.                         (* used to record the best match *)
  78.             longest_len: integer;
  79.                         (* longest extension we've found so far *)
  80.             posndx: longint;
  81.                         (* the index into the mappings database *)
  82.             info: FInfo;
  83.                         (* temporary for changing type and creator *)
  84.     begin
  85.         (* count the total number of entries *)
  86.         err := ICMapErr(ICMCountEntries(mappings, count));
  87.         if err <> noErr then begin
  88.             count := 0;
  89.         end; (* if *)
  90.         (* loop through the entries *)
  91.         (* looking for the longest match *)
  92.         longest_len := 0;
  93.         posndx := 0;
  94.         for i := 1 to count do begin
  95.             (* ICMGetEntry gets the entry from mappings *)
  96.             (* that starts at posndx *)
  97.             (* and puts it into the entry record *)
  98.             if ICMGetEntry(mappings, 
  99.                                         posndx, this) = noErr then begin
  100.                 (* increment posndx so that we get the next *)
  101.                 (* entry the next time around the loop *)
  102.                 posndx := posndx + this.total_length;
  103.                 (* the entry matches if *)
  104.                 (* not_incoming flag bit is clear *)
  105.                 (* it's longer than the previous max *)
  106.                 (* it's longer than the file name *)
  107.                 (* it matches the last N chars of the filename *)
  108.                 if not btst(this.flags,
  109.                                             ICmap_not_incoming_bit)
  110.                         & (length(this.extension) > longest_len)
  111.                         & (length(this.extension) < length(fss.name))
  112.                         & (IUEqualString(copy(fss.name,
  113.                                                                 length(fss.name)
  114.                                                                         - length(this.extension)
  115.                                                                         + 1,
  116.                                                                 255),
  117.                                                         this.extension) = 0) then begin
  118.                     (* record the new longest entry *)
  119.                     entry := this;
  120.                     longest_len := length(this.extension);
  121.                 end; (* if *)
  122.             end; (* if *)
  123.         end; (* for *)
  124.  
  125.         (* if we found any matches then *)
  126.         (* set the file type and creator appropriately *)
  127.         if longest_len > 0 then begin
  128.             err := HGetFInfo(fss.vRefNum, fss.parID, 
  129.                                 fss.name, info);
  130.             if err = noErr then begin
  131.                 info.fdCreator := entry.file_creator;
  132.                 info.fdType := entry.file_type;
  133.                 err := HSetFInfo(fss.vRefNum, fss.parID, 
  134.                                 fss.name, info);
  135.             end; (* if *)
  136.         end
  137.         else begin
  138.             err := noErr;
  139.         end; (* if *)
  140.  
  141.         quit_now := true;
  142.         ProcessDocument := err;
  143.     end; (* ProcessDocument *)
  144.  
  145. (* ***** AppleEvent Handlers ***** *)
  146.  
  147.     function HandleOpenApplication (theAppleEvent: AppleEvent;
  148.                             reply: AppleEvent;
  149.                             refcon: longint): OSErr;
  150.         (* the 'oapp' event handler, displays the about box *)
  151.         (* should most probably only do this if we're in *)
  152.         (* the foreground but that's just too complicated *)
  153.         (* for this example *)
  154.         var
  155.             err: OSErr;
  156.             email_address: Str255;
  157.             junk_attr: longint;
  158.             junk: integer;
  159.             junk_icerr: ICError;
  160.     begin
  161.         err := GotRequiredParams(theAppleEvent);
  162.         if err = noErr then begin
  163.             junk_icerr := ICGetPrefStr(instance, kICEmail, 
  164.                                                 junk_attr, email_address);
  165.             ParamText(email_address, '', '', '');
  166.             junk := Alert(128, nil);
  167.             quit_now := true;
  168.         end; (* if *)
  169.         HandleOpenApplication := err;
  170.     end; (* HandleOpenApplication *)
  171.  
  172.     function HandleOpenDocuments (theAppleEvent:AppleEvent;
  173.                             reply: AppleEvent;
  174.                             refcon: longint): OSErr;
  175.         (* a fairly standard 'odoc' event handler *)
  176.         (* gets the document list, counts the items in it *)
  177.         (* gets the FSSpec for each document and calls *)
  178.         (* ProcessDocument on it *)
  179.         var
  180.             fss: FSSpec;
  181.             doc_list: AEDescList;
  182.             index, item_count: longint;
  183.             junk_size: Size;
  184.             junk_keyword: AEKeyword;
  185.             junk_type: descType;
  186.             err, junk: OSErr;
  187.     begin
  188.         err := AEGetParamDesc(theAppleEvent, keyDirectObject,
  189.                             typeAEList, doc_list);
  190.         if err = noErr then begin
  191.             err := GotRequiredParams(theAppleEvent);
  192.             if err = noErr then begin
  193.                 err := AECountItems(doc_list, item_count);
  194.             end
  195.             else begin
  196.                 item_count := 0;
  197.             end; (* if *)
  198.             for index := 1 to item_count do begin
  199.                 if err = noErr then begin
  200.                     err := AEGetNthPtr(doc_list, index, typeFSS,
  201.                                         junk_keyword, junk_type,
  202.                                         @fss, sizeof(fss), junk_size);
  203.                     if err = noErr then begin
  204.                         err := ProcessDocument(fss);
  205.                     end; (* if *)
  206.                 end; (* if *)
  207.             end; (* for *)
  208.             junk := AEDisposeDesc(doc_list);
  209.         end; (* if *)
  210.         HandleOpenDocuments := err;
  211.     end; (* HandleOpenDocuments *)
  212.  
  213.     function HandleQuit (theAppleEvent:AppleEvent;
  214.                             reply: AppleEvent;
  215.                             refcon: longint): OSErr;
  216.         (* a fairly standard 'quit' event handler *)
  217.         (* sets quit_now so that the main event loop quits *)
  218.         var
  219.             err: OSErr;
  220.     begin
  221.         err := GotRequiredParams(theAppleEvent);
  222.         if err = noErr then begin
  223.             quit_now := true;
  224.         end; (* if *)
  225.         HandleQuit := err;
  226.     end; (* HandleQuit *)
  227.  
  228.     var
  229.         junkbool: boolean;
  230.         event: EventRecord;
  231.         err: OSErr;
  232.         junk: OSErr;
  233.         response: longint;
  234.         attr: longint;
  235. begin
  236.     (* First check for System 7.  OK, so we're supposed *)
  237.     (* to test for functionality but this is example *)
  238.     (* code. *)
  239.     if (Gestalt(gestaltSystemVersion, response) <> noErr)
  240.                 | (response < $700) then begin
  241.         ExitToShell;
  242.     end; (* if *)
  243.  
  244.     (* Now install our AppleEvent handles. *)
  245.     err := AEInstallEventHandler(kCoreEventClass,
  246.                             kAEOpenApplication,
  247.                             @HandleOpenApplication, 0, false);
  248.     if err = noErr then begin
  249.         err := AEInstallEventHandler(kCoreEventClass,
  250.                             kAEOpenDocuments,
  251.                             @HandleOpenDocuments, 0, false);
  252.     end; (* if *)
  253.     if err = noErr then begin
  254.         err := AEInstallEventHandler(kCoreEventClass,
  255.                             kAEQuitApplication,
  256.                             @HandleQuit, 0, false);
  257.     end; (* if *)
  258.  
  259.     (* startup Internet Config *)
  260.     if err = noErr then begin
  261.         err := ICMapErr(ICStart(instance, my_creator));
  262.         if err = noErr then begin
  263.             err := ICMapErr(ICFindConfigFile(instance, 0, nil));
  264.         end; (* if *)
  265.  
  266.     (* fetch the mappings preference *)
  267.         if err = noErr then begin
  268.             err := ICMapErr(ICGetPrefHandle(instance, kICMapping, 
  269.                                     attr, mappings));
  270.         end; (* if *)
  271.  
  272.     (* enter main loop *)
  273.         if err = noErr then begin
  274.             quit_now := false;
  275.             while not quit_now do begin
  276.                 junkbool := WaitNextEvent(everyEvent, event, 
  277.                                                 maxlongint, nil);
  278.                 case event.what of
  279.                     keyDown: 
  280.                         quit_now := true;
  281.                     kHighLevelEvent: 
  282.                         junk := AEProcessAppleEvent(event);
  283.                     otherwise
  284.                         ;
  285.                 end; (* case *)
  286.             end; (* while *)
  287.         end; (* if *)
  288.  
  289.         (* shut down IC, only if we successfully started it *)
  290.         junk := ICStop(instance);
  291.     end; (* if *)
  292.  
  293.     (* beep if we get any errors*)
  294.     (* sophisticated error handling this is not *)
  295.     (* a good place to put a breakpoint this is *)
  296.     if err <> noErr then begin
  297.         SysBeep(10);
  298.     end; (* if *)
  299. end. (* SpaceAliens *)
  300.